package com.av.db.layer.impl;

import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.av.db.dataobjects.Adeudo;
import com.av.db.dataobjects.Tarjeta;
import com.av.db.layer.interfaces.AdeudoLayer;
import com.av.exceptions.AvException;

/**
 * Clase que contiene la implementacion de funciones para la tabla de adeudos
 * utilizando la tecnologia de Hibernate
 * 
 * @author J Francisco Ruvalcaba C
 * 
 */
public class AdeudoLayerImpl extends HibernateDaoSupport implements AdeudoLayer {

	private static Logger log = Logger.getLogger(AdeudoLayerImpl.class);

	/**
	 * Funcion que actualiza en la base de datos un adeudo en especifo
	 */
	@Override
	public void actualizar(Adeudo adeudo) throws AvException {
		log.info("Inicio - actualizar(Adeudo adeudo)");
		log.debug("Id : " + adeudo.getId());
		log.debug("Adeudo : " + adeudo.toString());

		if (adeudo == null) {
			log.error("No se puede actualizar un adeudo nulo");
			throw new AvException("Adeudo nulo a ser actualizado");
		}

		if (adeudo.getId() < 0) {
			log.error("No se puede actualizar un adeudo con identificador "
					+ "invalido");
			throw new AvException("Adeudo con identificador invalido a ser "
					+ "actualizado");
		}

		getHibernateTemplate().update(adeudo);

		log.info("Fin - actualizar(Adeudo adeudo)");
	}// actualizar

	/**
	 * Funcion que agrega en la base de datos configura un nuevo adeudo
	 */
	@Override
	public void agregar(Adeudo adeudo) throws AvException {
		log.info("Inicio - agregar(Adeudo adeudo)");
		log.debug("Adeudo : " + adeudo.toString());

		if (adeudo == null) {
			log.error("No se puede agregar un adeudo nulo");
			throw new AvException("Adeudo nulo a ser agregado");
		}

		getHibernateTemplate().save(adeudo);

		log.info("Fin - agregar(Adeudo adeudo)");
	}// agregar

	/**
	 * Funcion que elimina un adeudo especifico de la base de datos configurada
	 */
	@Override
	public void eliminar(Adeudo adeudo) throws AvException {
		log.info("Inicio - eliminar(Adeudo adeudo)");
		log.debug("Adeudo : " + adeudo.toString());

		if (adeudo == null) {
			log.error("No se puede eliminar un adeudo nulo");
			throw new AvException("Adeudo nulo a ser eliminado");
		}

		if (adeudo.getId() < 0) {
			log
					.error("No se puede eliminar un adeudo con identificador negativo");
			throw new AvException("Identificador negativo");
		}

		getHibernateTemplate().delete(adeudo);

		log.info("Fin - eliminar(Adeudo adeudo)");
	}// eliminar

	/**
	 * Funcion que obtiene un adeudo de la base de datos configurada a partir de
	 * su identificador
	 */
	@Override
	public Adeudo obtener(int id) {
		log.info("Inicio - obtener(int id)");
		log.debug("Id : " + id);

		if (id < 0) {
			log
					.warn("No se puede obtener un adeudo con identificador negativo");
			return null;
		}

		Adeudo tmp = getHibernateTemplate().get(Adeudo.class, id);

		if (tmp != null) {
			log.debug("Adeudo : " + tmp.toString());
		} else {
			log.debug("Adeudo no encontrado");
		}

		log.info("Fin - obtener(int id)");

		return tmp;
	}// obtener

	/**
	 * Funcion que obtiene el conjunto de todos los adeudos registrados en la
	 * base de datos configurada
	 */
	@Override
	public Adeudo[] obtener() {
		log.info("Inicio - obtener()");

		List<?> l = getSession().createCriteria(Adeudo.class)
				.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).addOrder(
						Order.asc(Adeudo.ID)).list();

		Adeudo[] tmp = null;
		if (l != null && l.size() > 0) {
			log.debug("Cantidad obtenida : " + l.size());
			tmp = new Adeudo[l.size()];
			l.toArray(tmp);
		}

		log.info("Fin - obtener()");

		return tmp;
	}// obtener

	/**
	 * Funcion que obtiene los adeudos cargados en una tarjeta en especifico
	 */
	@Override
	public Adeudo[] obtener(Tarjeta t) {
		log.info("Inicio - obtener(Tarjeta t)");

		List<?> l = getSession().createCriteria(Adeudo.class).add(
				Restrictions.eq(Adeudo.TARJETA, t)).setResultTransformer(
				Criteria.DISTINCT_ROOT_ENTITY).addOrder(Order.asc(Adeudo.ID))
				.list();

		Adeudo[] tmp = null;
		if (l != null && l.size() > 0) {
			log.debug("Cantidad obtenida : " + l.size());
			tmp = new Adeudo[l.size()];
			l.toArray(tmp);
		}

		log.info("Fin - obtener(Tarjeta t)");

		return tmp;
	}// obtener
}// AdeudoLayerImpl
